package pers.cz.business;

import pers.cz.mapper.DatabaseDesignConfMappingMapper;
import pers.cz.mapper.DatabaseDesignConfigMapper;
import pers.cz.mapper.DatabaseDesignDtlMapper;
import pers.cz.mapper.DatabaseDesignMapper;
import pers.cz.model.DatabaseDesign;
import pers.cz.model.DatabaseDesignConfMapping;
import pers.cz.model.DatabaseDesignConfig;
import pers.cz.model.DatabaseDesignDtlWithBLOBs;
import pers.cz.pub.AbstractBusiness;
import pers.cz.pub.SequenceEnum;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: PostGirl-panent
 * @description:
 * @author: Cheng Zhi
 * @create: 2022-08-14 15:36
 **/
public class DatabaseDesignBusiness extends AbstractBusiness {

    public List<DatabaseDesign> getAllDatabaseDesignByUserId(Integer userId) {

        List<DatabaseDesign> allDatabaseDesignByUserId = getMapper(DatabaseDesignMapper.class).selectAllByUserId(userId);

        // 2、从List中获取所有的父亲节点
        List<DatabaseDesign> allParentNode = getAllParentNode(allDatabaseDesignByUserId);
        // 3、根据父亲节点获取所有的递归子节点

        Map<Integer, List<DatabaseDesign>> map = transformMap(allDatabaseDesignByUserId);
        recursionChild(allParentNode, map);
        return  allParentNode;
    }

    /**
     * 将数据转换为Map,其中键为父节点id, 值为，该节点下的所有直系子节点
     * @param allDatabaseDesign
     * @return
     */
    public Map<Integer, List<DatabaseDesign>> transformMap(List<DatabaseDesign> allDatabaseDesign) {
        Map<Integer, List<DatabaseDesign>> parentMap = new HashMap<>();
        for (DatabaseDesign databaseDesign : allDatabaseDesign) {
            List<DatabaseDesign> databaseDesigns = parentMap.get(databaseDesign.getParentId());
            if (databaseDesigns == null || databaseDesigns.isEmpty()) {
                databaseDesigns = new ArrayList<DatabaseDesign>();
            }
            databaseDesigns.add(databaseDesign);
            parentMap.put(databaseDesign.getParentId(), databaseDesigns);
        }
        return parentMap;
    }

    public void recursionChild(List<DatabaseDesign> result, Map<Integer, List<DatabaseDesign>> map) {

        if (result == null) {
            return;
        }
        for (DatabaseDesign databaseDesign : result) {
            Integer parentId = databaseDesign.getId();
            List<DatabaseDesign> childrenByParentId = map.get(parentId);
            recursionChild(childrenByParentId, map);
            databaseDesign.setChildren(childrenByParentId);
        }
    }

    public List<DatabaseDesign> getChildrenByParentId(Integer parentId, List<DatabaseDesign> allDatabaseDesign) {
        List<DatabaseDesign> children = new ArrayList<>();

        for (DatabaseDesign databaseDesign : allDatabaseDesign) {
            if (databaseDesign.getParentId() != null && parentId.equals(databaseDesign.getParentId())) {
                children.add(databaseDesign);
            }
        }
        return children;
    }

    private List<DatabaseDesign> getAllParentNode(List<DatabaseDesign> allDatabaseDesign) {
        List<DatabaseDesign> list = new ArrayList<DatabaseDesign>();
        for (DatabaseDesign databaseDesign : allDatabaseDesign) {

            if (databaseDesign.getParentId() == null) {
                list.add(databaseDesign);
            }
        }
        return list;
    }

    /**
     * 添加一个节点
     * @param databaseDesign
     * @return
     */
    public Integer addNode(DatabaseDesign databaseDesign) {
        databaseDesign.setId(Integer.valueOf(cPublicFunc.getSoNbr(SequenceEnum.DATA_MODELING_SEQUENCE).toString()));
        int i = this.getMapper(DatabaseDesignMapper.class).insertSelective(databaseDesign);
        return i;
    }

    public Integer updateNode(DatabaseDesign databaseDesign) {
        int i = this.getMapper(DatabaseDesignMapper.class).updateByPrimaryKeySelective(databaseDesign);
        return i;
    }

    public Integer deleteNode(DatabaseDesign databaseDesign) {
       return this.getMapper(DatabaseDesignMapper.class).deleteByPrimaryKey(databaseDesign.getId());
    }

    public Integer addDtl(DatabaseDesignDtlWithBLOBs databaseDesignDtlWithBLOBs) {
        return this.getMapper(DatabaseDesignDtlMapper.class).insertSelective(databaseDesignDtlWithBLOBs);
    }

    public Integer removeDtl(Integer id) {
        return this.getMapper(DatabaseDesignDtlMapper.class).deleteByPrimaryKey(id);
    }

    public Integer updateDtl(DatabaseDesignDtlWithBLOBs databaseDesignDtlWithBLOBs) {
        return this.getMapper(DatabaseDesignDtlMapper.class).updateByPrimaryKeySelective(databaseDesignDtlWithBLOBs);
    }

    public DatabaseDesignDtlWithBLOBs queryDtl(Integer id) {
        return this.getMapper(DatabaseDesignDtlMapper.class).selectByPrimaryKey(id);
    }

    /**
     * 同时添加一个节点和对应的数据表
     * @param databaseDesignDtlWithBLOBs
     * @param databaseDesign
     * @return
     */
    public Integer addDtlAndNode(DatabaseDesignDtlWithBLOBs databaseDesignDtlWithBLOBs, DatabaseDesign databaseDesign) {
        Integer id = Integer.valueOf(cPublicFunc.getSoNbr(SequenceEnum.DATA_MODELING_SEQUENCE).toString());
        databaseDesign.setId(id);
        int i = this.getMapper(DatabaseDesignMapper.class).insertSelective(databaseDesign);
        databaseDesignDtlWithBLOBs.setId(id);
        this.getMapper(DatabaseDesignDtlMapper.class).insertSelective(databaseDesignDtlWithBLOBs);
        return i;
    }

    public Integer addConf(DatabaseDesignConfig databaseDesignConfig) {
        return this.getMapper(DatabaseDesignConfigMapper.class).insert(databaseDesignConfig);
    }

    public Integer updateConf(DatabaseDesignConfig databaseDesignConfig) {
        return this.getMapper(DatabaseDesignConfigMapper.class).updateByPrimaryKeySelective(databaseDesignConfig);
    }

    public Integer deleteConf(Long id) {
        return this.getMapper(DatabaseDesignConfigMapper.class).deleteByPrimaryKey(id);
    }

    public List<DatabaseDesignConfig> queryDatabaseConfs() {

        List<DatabaseDesignConfig> databaseDesignConfigs = this.getMapper(DatabaseDesignConfigMapper.class).selectAll();
        for (DatabaseDesignConfig databaseDesignConfig : databaseDesignConfigs) {
            List<DatabaseDesignConfMapping> databaseDesignConfMappings = this.getMapper(DatabaseDesignConfMappingMapper.class).selectMappingList(databaseDesignConfig.getType());
            databaseDesignConfig.setFields(databaseDesignConfMappings);
        }
        return databaseDesignConfigs;
    }

    public Integer addFields(DatabaseDesignConfig databaseDesignConfig) {
        this.getMapper(DatabaseDesignConfigMapper.class).insertSelective(databaseDesignConfig);

        this.getMapper(DatabaseDesignConfMappingMapper.class).batchInsert(databaseDesignConfig.getFields());

        return SDL_ONCE;
    }

    public Integer updateFields(DatabaseDesignConfig databaseDesignConfig) {

        this.getMapper(DatabaseDesignConfigMapper.class).updateByPrimaryKeySelective(databaseDesignConfig);

        this.getMapper(DatabaseDesignConfMappingMapper.class).batchUpdate(databaseDesignConfig.getFields());
        return SDL_ONCE;
    }

    public Integer deleteFields(DatabaseDesignConfig databaseDesignConfig) {
        this.getMapper(DatabaseDesignConfigMapper.class).deleteByPrimaryKey(databaseDesignConfig.getId());
        this.getMapper(DatabaseDesignConfMappingMapper.class).batchDelete(databaseDesignConfig.getFields().get(0));
        return SDL_ONCE;
    }

}
